package com.etcfg.etlaunch;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class FileDownloader {

	private String targetUrl;
	private OutputStream outputStream;
	private JProgressBar progressBar;
	private JLabel statusLabel = new JLabel();
	private boolean canceled = false;
	private JDialog dialog;
	private String downloadMessage;
	private Exception exception;
	private boolean modal = false;
	private Window parent;

	public FileDownloader(String url, OutputStream target,
			String downloadTitle, Window parent, boolean modal) {
		this.targetUrl = url;
		this.outputStream = target;
		this.downloadMessage = downloadTitle;
		this.modal = modal;
		this.parent = parent;

	}

	public FileDownloader(String url, OutputStream target) {
		this.targetUrl = url;
		this.outputStream = target;
	}

	public void startDownload() {

		Thread thread = new Thread() {
			@Override
			public void run() {
				downloadFile();
			}

		};
		thread.start();
		showProgressDialog();

	}

	private void showProgressDialog() {
		JPanel progressPart = new JPanel();
		progressPart.setLayout(new GridBagLayout());
		GridBagConstraints bc = new GridBagConstraints();
		bc.anchor = GridBagConstraints.CENTER;
		bc.gridx = 0;
		bc.gridy = 0;
		bc.insets = new Insets(3, 3, 3, 3);
		statusLabel = new JLabel(downloadMessage);
		progressBar = new JProgressBar();
		progressBar.setValue(1);
		progressBar.setStringPainted(true);
		progressPart.add(statusLabel, bc);
		bc.gridy = 1;
		bc.weighty = 1;
		bc.weightx = 5;
		bc.fill = GridBagConstraints.HORIZONTAL;
		progressPart.add(progressBar, bc);
		JButton button = new JButton("Cancel");
		bc.gridy = 2;
		bc.weightx = 1;
		bc.weighty = 0;
		bc.fill = GridBagConstraints.NONE;
		progressPart.add(button, bc);
		button.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				canceled = true;
			}
		});
		dialog = new JDialog(parent);
		dialog.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		dialog.setContentPane(progressPart);
		dialog.setLocationRelativeTo(parent);
		dialog.setModal(true);
		dialog.setSize(300, 150);

		dialog.setVisible(true);

	}

	public static void main(String[] args) {
		try {
			// Set System L&F
			UIManager
					.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); //$NON-NLS-1$
		} catch (UnsupportedLookAndFeelException e) {
			// handle exception
		} catch (ClassNotFoundException e) {
			// handle exception
		} catch (InstantiationException e) {
			// handle exception
		} catch (IllegalAccessException e) {
			// handle exception
		}
		ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
		final FileDownloader downloader = new FileDownloader(
				"http://etcfglaunch.googlecode.com/files/etcfgLaunch_setup_0_17_beta.exe",
				arrayOutputStream, "Downloading etcfgLaunch 0.17", null, true);
		downloader.startDownload();

	}

	public boolean isCanceled() {
		return canceled;
	}

	public Exception getException() {
		return exception;
	}

	public void downloadFile() {
		try {
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			URL url = new URL(targetUrl);
			HttpURLConnection connection = (HttpURLConnection) url
					.openConnection();
			connection.connect();
			final int contentLength = connection.getContentLength();
			System.out.println("Content length " + contentLength);
			SwingUtilities.invokeLater(new Runnable() {

				@Override
				public void run() {
					if (progressBar == null) {
						return;
					}
					try {
						progressBar.setMaximum(contentLength);
					} catch (Exception e) {
						e.printStackTrace();
					}

				}
			});

			InputStream inputStream = connection.getInputStream();
			byte[] bytes = new byte[1024];

			while (true) {
				if (canceled) {
					break;
				}
				final int read = inputStream.read(bytes);
				if (read <= 0) {
					break;
				}
				SwingUtilities.invokeLater(new Runnable() {

					@Override
					public void run() {
						if (progressBar == null) {
							return;
						}
						progressBar.setValue(progressBar.getValue() + read);
						progressBar.setString("Downloaded "
								+ progressBar.getValue() + " bytes of "
								+ contentLength);

					}
				});
				outputStream.write(bytes, 0, read);

			}
			inputStream.close();
			connection.disconnect();
			if (dialog != null) {
				dialog.setVisible(false);
				dialog.dispose();
			}
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (final IOException e) {
			SwingUtilities.invokeLater(new Runnable() {

				@Override
				public void run() {
					JOptionPane.showMessageDialog(dialog, "Download failed! "
							+ e.getMessage(), "", JOptionPane.ERROR_MESSAGE);

				}
			});
		}
	}

}
